

#include "ResultSet.h"
#include <cassert>

namespace db
{

ResultSet::ResultSet(MYSQL_RES* mysql_res, MYSQL* mysql)
:
	mysql_res_(mysql_res)
{
	if (mysql_res_ != NULL)
	{
		num_columns_ = mysql_num_fields(mysql_res_);
		num_rows_ = mysql_num_rows(mysql_res_);
		cursor_ = -1;
	}
	else
	{
		// empty set.
		num_columns_ = 0;
		num_rows_ = 0;
		cursor_ = -1;
	}

	if (mysql != NULL)
	{
		affected_rows_ = mysql_affected_rows(mysql);
		inserted_id_ = mysql_insert_id(mysql);
	}
	else
	{
		affected_rows_ = 0;
		inserted_id_ = 0;
	}
}

ResultSet::~ResultSet()
{
	mysql_free_result(mysql_res_);
}

void ResultSet::reset()
{
	cursor_ = -1;
}

bool ResultSet::next()
{
	cursor_++;
	if (cursor_ >= num_rows_ || cursor_ < 0)
	{
		return false;
	}
	else
	{
		mysql_data_seek(mysql_res_, cursor_);
		cur_row_ = mysql_fetch_row(mysql_res_);
		cur_lengths_ = mysql_fetch_lengths(mysql_res_);
		return true;
	}
}

int	ResultSet::getCurLength(size_t column)
{
	if (!isValid(column))
	{
		return -1;
	}

	return cur_lengths_[column];
}

bool ResultSet::isNull(size_t column)
{
	if (!isValid(column))
	{
		return true;
	}
	return cur_row_[column] == NULL;
}

bool ResultSet::getBoolean(size_t column)
{
	if (!isNull(column))
	{
		return atoi(cur_row_[column]) != 0;
	}
	else 
	{
		return false;
	}

}

int32 ResultSet::getInt32(size_t column)
{
	if (!isNull(column))
	{
		return atoi(cur_row_[column]);
	}
	else 
	{
		return 0;
	}
}

uint32 ResultSet::getUint32(size_t column)
{
	if (!isNull(column))
	{
		return atoi(cur_row_[column]);
	}
	else 
	{
		return 0U;
	}
}

int64 ResultSet::getInt64(size_t column)
{
	if (!isNull(column))
	{
		return _atoi64(cur_row_[column]);
	}
	else 
	{
		return 0LL;
	}
}
uint64 ResultSet::getUint64(size_t column)
{
	if (!isNull(column))
	{
		return _atoi64(cur_row_[column]);
	}
	else 
	{
		return 0ULL;
	}
}

float ResultSet::getFloat(size_t column)
{
	if (!isNull(column))
	{
		return (float)atof(cur_row_[column]);
	}
	else 
	{
		return 0.0f;
	}
}

double ResultSet::getDouble(size_t column)
{
	if (!isNull(column))
	{
		return atof(cur_row_[column]);
	}
	else 
	{
		return 0.0f;
	}

}

std::string ResultSet::getString(size_t column)
{
	if (!isNull(column))
	{
		return std::string(cur_row_[column], cur_lengths_[column]);
	}
	else 
	{
		return std::string();
	}
}

bool ResultSet::getBinary(size_t column, void* pBuff, unsigned long nBuffLen)
{
	if ( cur_lengths_[column] > nBuffLen)
	{
		fprintf(stderr, "getBinary buff is not enough.\n");
		return false;
	}
	memcpy_s( pBuff,nBuffLen, cur_row_[column], cur_lengths_[column]);
	return true;
}

bool ResultSet::isValid(size_t column)
{
	if (cursor_ < 0 || cursor_ >= num_rows_)
	{
		fprintf(stderr, "row %d out of range.\n", cursor_);
		return false;
	}
	else if (column >= num_columns_)
	{
		fprintf(stderr, "column %u out of range.\n", column);
		return false;
	}
	else
	{
		return true;
	}
}

} // end namespace db